#region Copyright Notice
// 
// 
//  
//  Copyright (c) 2009-2011 Anindya Chatterjee
//  
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//  
//      http://www.apache.org/licenses/LICENSE-2.0
//  
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// 
// 
#endregion
using System;
using System.Collections.Generic;

namespace AbstractClass.Linq
{
    /// <summary>
    ///   Exposes some extension methods for <see cref = "IList{T}" />
    /// </summary>
    public static class ListExtensions
    {
        #region | Code Taken from Mannex Library |

        /// <summary>
        ///   Slices the specified list starting from <paramref name="start" />.
        /// </summary>
        /// <typeparam name="T">The type of the elements in the list.</typeparam>
        /// <param name="list">The list to slice.</param>
        /// <param name="start">The start position for slicing.</param>
        /// <returns>A sequence of elements obtained by slicing the <paramref name="list"/>.</returns>
        public static IEnumerable<T> Slice<T>(this IList<T> list, int start)
        {
            if (list == null) throw new ArgumentNullException("list");
            return list.Slice(start, list.Count);
        }

        /// <summary>
        ///   Slices the specified list starting from <paramref name="start"/> up to <paramref name="end"/>.
        /// </summary>
        /// <typeparam name="T">The type of the elements in the list.</typeparam>
        /// <param name="list">The list to slice.</param>
        /// <param name="start">The start position for slicing.</param>
        /// <param name="end">The slicing end position.</param>
        /// <returns>A sequence of elements obtained by slicing the <paramref name="list"/>.</returns>
        public static IEnumerable<T> Slice<T>(this IList<T> list, int start, int end)
        {
            if (list == null) throw new ArgumentNullException("list");
            for (int i = list.ClipIndex(start); i < list.ClipIndex(end); i++)
                yield return list[i];
        }

        private static int ClipIndex<T>(this ICollection<T> collection, int index)
        {
            return Math.Min(collection.Count, index < 0 ? Math.Max(0, collection.Count + index) : index);
        }

        #endregion
    }
}